package com.zros.modules.system.controller;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;

import lombok.extern.slf4j.Slf4j;

import org.mindrot.jbcrypt.BCrypt;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cglib.beans.BeanCopier;
import org.springframework.context.annotation.PropertySource;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import springfox.documentation.annotations.ApiIgnore;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zros.common.api.vo.Result;
import com.zros.common.constant.ResponseConstant;
import com.zros.common.util.RedisUtil;
import com.zros.modules.shiro.authc.util.JwtUtil;
import com.zros.modules.system.dto.LoginUser;
import com.zros.modules.system.dto.UserInfo;
import com.zros.modules.system.entity.DataResource;
import com.zros.modules.system.entity.Organization;
import com.zros.modules.system.entity.Resource;
import com.zros.modules.system.entity.Role;
import com.zros.modules.system.entity.User;
import com.zros.modules.system.service.IDataResourceService;
import com.zros.modules.system.service.IOrganizationUserService;
import com.zros.modules.system.service.IResourceService;
import com.zros.modules.system.service.IRoleResourceService;
import com.zros.modules.system.service.IUserRoleService;
import com.zros.modules.system.service.IUserService;

/**
 * @ClassName: LoginController
 * @Description: 登录相关前端控制器
 * 
 * @date 2018年5月18日 下午4:08:26
 */
@Slf4j
@RestController
@RequestMapping("/auth")
@Api(value = "LoginController|登录鉴权相关的前端控制器")
public class LoginController {

	@Autowired
	private IUserService userService;

	@Autowired
	private IUserRoleService userRoleService;

	@Autowired
	private IResourceService resourceService;

	@Autowired
	private IOrganizationUserService organizationUserService;

//	@Autowired
//	private IDataResourceService dataResourceService;
	
	@Autowired
    private IRoleResourceService roleResourceService;
	
	@Autowired
	private RedisUtil redisUtil;

	@Value("${system.prefixUserToken}")
	private String prefixUserToken;
	

	@PostMapping("/login")
	@ApiOperation(value = "执行登录", notes = "返回token")
	public Result<String> login(@RequestBody LoginUser loginUser, HttpServletRequest request) throws Exception {
		String userAccount = loginUser.getUserAccount();
		String userPassword = loginUser.getUserPassword();

		log.info("查询当前页："); // 查询用户是否存在
		QueryWrapper<User> ew = new QueryWrapper<>();
		ew.and(e -> e.eq("user_account", userAccount).or().eq("user_mobile", userAccount).or().eq("user_email", userAccount) );
		
		//ew.eq("user_account", userAccount).or().eq("user_mobile", userAccount).or().eq("user_email", userAccount);
		//ew.eq("user_account", userAccount);

		User user = userService.getOne(ew);
		if (StringUtils.isEmpty(user) || !BCrypt.checkpw(userPassword, user.getUserPassword())) {
			return new Result<String>().error(ResponseConstant.INVALID_USERNAME_PASSWORD);
		}
		// 判断用户状态
		if (user.getUserStatus().equals("0")) { 
			//throw new AuthenticationException("账号已被锁定,请联系管理员!");
			return new Result<String>().error(ResponseConstant.INVALID_USER_1);
		}
		
		// 生成token
		String token = JwtUtil.sign(user.getUserAccount(), user.getUserPassword());
//		redisUtil.set(CommonConstant.PREFIX_USER_TOKEN + token, token); // 设置超时时间
//		redisUtil.expire(CommonConstant.PREFIX_USER_TOKEN + token, JwtUtil.EXPIRE_TIME / 1000);

		redisUtil.set(prefixUserToken+userAccount, token); // 设置超时时间
		redisUtil.expire(userAccount, JwtUtil.EXPIRE_TIME / 1000);

		return new Result<String>().success().put(token);
	}

	/**
	 * 获取登录后的用户信息
	 */
	@GetMapping("/user/info")
	// @RequiresAuthentication
	@ApiOperation(value = "登录后获取用户个人信息")
	public Result<UserInfo> userInfo(HttpServletRequest request) {

		User currentUser = new User();
		String userAccount = JwtUtil.getUserAccountByToken(request);
		currentUser = userService.queryUserByAccount(userAccount);
		Long userId = currentUser.getId();

		UserInfo userInfo = new UserInfo();
		BeanCopier.create(User.class, UserInfo.class, false).copy(currentUser, userInfo, null);

		List<Role> userRole = userRoleService.queryRolesByUserId(userId);
		if (!CollectionUtils.isEmpty(userRole)) 
		{
			List<String> roles = new ArrayList<String>();
			String roleNames = new String();
			
			for (Role role : userRole) {
				roles.add(role.getRoleKey());
				roleNames += role.getRoleName() + " ";
			}
			userInfo.setRoles(roles);
			userInfo.setRoleName(roleNames);
		}

		userInfo.setResources(resourceService.queryResourceByUserId(userId));
		
		// 从数据库获取当前用户的权限
		Set<String> permissionSet = new HashSet<>();
        for (Role role : userRole) {
            for (Resource res : roleResourceService.queryResourceByRoleId(role.getId())) {
                if (!StringUtils.isEmpty(res.getResourceKey())) {
                    if (!StringUtils.isEmpty(res.getResourceKey().replace(" ", ""))) {
                    	permissionSet.add(res.getResourceKey());
                    }
                }
            }
        }
		userInfo.setRes(permissionSet);

		// 机构信息
		List<Organization> userOrg = organizationUserService.queryOrgsByUserId(userId);
		if (!CollectionUtils.isEmpty(userOrg)) 
		{
			String orgNames = new String();
			for (Organization organization : userOrg) {
				orgNames += organization.getOrganizationName() + " ";
			}
			userInfo.setOrgName(orgNames);
		}
		// 数据权限信息
//		List<DataResource> userDataRes = dataResourceService.queryDataResourceByUserId(userId, "queryClueOrStatistic");
//		if (!CollectionUtils.isEmpty(userDataRes)) {
//			userInfo.setDataResourceKey(userDataRes.get(0).getDataResourceKey());
//		}

		return new Result<UserInfo>().success().put(userInfo);
	}

	@PostMapping("/logout")
	@ApiOperation(value = "退出登录")
	public Result<?> logOut(HttpServletRequest request) throws Exception {
		return new Result<>().success();
	}

	@RequestMapping("401")
	@ApiIgnore
	public Result<?> unauthorized() {
		return new Result<>().error(ResponseConstant.USER_NO_PERMITION);
	}

	@RequestMapping("timeout")
	@ApiIgnore
	public Result<?> timeOut() {
		return new Result<>().error(ResponseConstant.UNAUTHORIZED);
	}

	@RequestMapping("chongfudenglu")
	@ApiIgnore
	public Result<?> chongfudenglu() {
		return new Result<>().error(ResponseConstant.chongfudenglu);
	}
}
